home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 526-550 / disk_549 / ffex / source / ffex.mod < prev    next >
Text File  |  1992-05-06  |  18KB  |  526 lines

  1. (* Modul    : FFEX                             *)
  2. (* Projekt  : FFEX (Fast Fractal Exploration Set)             *)
  3. (* Autor    : Robert Brandner                         *)
  4. (* Funktion : Hauptmodul von FFEX - Menüabfragen, Zoom, Berechnungen ... *)
  5. (* Copyright: Robert Brandner                         *)
  6. (*          Schillerstr. 3                         *)
  7. (*          A-8280 Fürstenfeld                     *)
  8. (*          AUSTRIA                             *)
  9.  
  10. MODULE FFEX;
  11.  
  12. FROM Menu      IMPORT SetMenu, MenuNum, ItemNum, SubNum, NextSelect;
  13. FROM Render    IMPORT SetPixel,GetPixel,FastIter16,FastIter32,LongRealIter,
  14.                       SetNormalPointer,SetZZZPointer,SetZoomPointer;
  15. FROM Request   IMPORT Info, GetLimits, Request;
  16. FROM ArpReq    IMPORT GetFileName;
  17. FROM IlbmInOut IMPORT LoadILBM, SaveILBM;
  18.  
  19. FROM Arts      IMPORT Assert, TermProcedure;
  20. FROM SYSTEM    IMPORT ADR, ADDRESS, CAST, INLINE, LONGSET;
  21. FROM GfxMacros IMPORT RasSize;
  22. FROM Graphics  IMPORT ViewModes,ViewModeSet,FontFlags,FontFlagSet,
  23.                       TextFontPtr, OpenFont,normalFont,TextAttr,CloseFont,
  24.                       LoadRGB4, SetRGB4, RastPortPtr,RectFill,SetAPen,
  25.                       SetRast, Move, Draw, SetDrMd, DrawModeSet,DrawModes,
  26.                       jam1, BltBitMap;
  27. FROM Intuition IMPORT IntuiMessagePtr, menuNull, ShowTitle, ModifyIDCMP,
  28.                 ScreenPtr,NewScreen,OpenScreen,CloseScreen,
  29.               WindowPtr,NewWindow,OpenWindow,CloseWindow,
  30.               WindowFlags,WindowFlagSet,ScreenFlags,ScreenFlagSet,
  31.               customScreen, IDCMPFlagSet, IDCMPFlags, ScreenToFront,
  32.               ClearMenuStrip, menuDown, menuUp, selectDown, selectUp;
  33. FROM Exec      IMPORT FindTask, TaskPtr, GetMsg, ReplyMsg, WaitPort, CopyMem;
  34. FROM Dos       IMPORT ProcessPtr;
  35.  
  36. CONST
  37.   SCREENTITLE="Fast Fractal Exploration Set 4.0";
  38.   TOPAZ="topaz.font";
  39.   LIMIT=4; (* bis zu dieser Größe werden Rechtecke gevierte(i)lt *)
  40.   ESCAPE=045H;
  41.   MENUFLAGS=IDCMPFlagSet{menuVerify,menuPick,mouseButtons};
  42.   STARTPIC="FFEXStart.pic";
  43.  
  44. TYPE
  45.   IterProc=PROCEDURE(LONGREAL,LONGREAL,LONGINT):LONGINT;
  46.  
  47. VAR
  48.   ns        : NewScreen;
  49.   nw        : NewWindow;
  50.   Iterations: IterProc;
  51.   win       : WindowPtr;
  52.   scr       : ScreenPtr;
  53.   topaz80   : TextFontPtr;
  54.   attr      : TextAttr;
  55.   thisTask  : ProcessPtr;
  56.   QUIT,title: BOOLEAN;
  57.   yadr      : ARRAY[0..512] OF LONGINT;
  58.   rp        : RastPortPtr;
  59.   msg       : IntuiMessagePtr;
  60.   class     : IDCMPFlagSet;
  61.   code      : CARDINAL;
  62.   xres,yres,depth,i,maxcol: INTEGER;
  63.   xmin,ymin,xmax,ymax     : LONGREAL; (* Koord. des zu zeichnenden Bildes *)
  64.   xminr,yminr,xmaxr,ymaxr : LONGREAL; (* Koord. des letzten gez. Bildes *)
  65.   x1,y1,x2,y2             : LONGREAL; (* Hilfsvariablen *)
  66.   maxiter                 : LONGINT;
  67.   zx,zy,zdx,zdy           : INTEGER;  (* Zoomrahmen *)
  68.   fileok    : BOOLEAN;
  69.   fname     : ARRAY[0..255] OF CHAR;  (* für Filerequester *)
  70.   saved     : BOOLEAN;
  71.   mess      : ARRAY[0..80] OF CHAR;
  72.   no,yes    : ARRAY[0..9] OF CHAR;
  73.  
  74. PROCEDURE TextColorsOn; FORWARD;
  75. PROCEDURE TextColorsOff; FORWARD;
  76. PROCEDURE CreateDisplay(w,h,d:INTEGER); FORWARD;
  77.  
  78. PROCEDURE LoadIff(fn:BOOLEAN);
  79.   VAR
  80.     i,planebytes,ok:LONGINT;
  81.     lscr:ScreenPtr;
  82.   BEGIN
  83.     IF NOT saved THEN
  84.       mess:="This picture is not saved!|If you continue, it will be lost!";
  85.       yes:="CONTINUE"; no:="CANCEL";
  86.       IF NOT Request(win,mess,yes,no) THEN RETURN END;
  87.     END;
  88.     INCL(win^.flags,rmbTrap);
  89.     ModifyIDCMP(win,IDCMPFlagSet{});
  90.     IF fn THEN
  91.       TextColorsOn;
  92.       fileok:=GetFileName(win,ADR("Load File"),ADR(fname));
  93.       TextColorsOff;
  94.     ELSE
  95.       fileok:=TRUE
  96.     END;
  97.     IF fileok THEN
  98.       SetZZZPointer(win);
  99.       fileok:=LoadILBM(fname,win,lscr,xminr,yminr,xmaxr,ymaxr,maxiter);
  100.       IF fileok THEN
  101.         xmin:=xminr; ymin:=yminr; xmax:=xmaxr; ymax:=ymaxr;
  102.         IF (lscr^.width#xres) OR (lscr^.height#yres) THEN
  103.           CreateDisplay(lscr^.width,lscr^.height,INTEGER(lscr^.bitMap.depth));
  104.         END;
  105.         saved:=TRUE;
  106.         ShowTitle(scr,FALSE);
  107.         ok:=BltBitMap(ADR(lscr^.bitMap),0,0,ADR(scr^.bitMap),0,0,
  108.                       xres,yres,0C0H,0FFH,NIL);
  109.         ShowTitle(scr,title);
  110.         CloseScreen(lscr);
  111.       END;
  112.       SetNormalPointer(win);
  113.     END;
  114.     EXCL(win^.flags,rmbTrap);
  115.     ModifyIDCMP(win,MENUFLAGS);
  116.   END LoadIff;
  117.  
  118. PROCEDURE SaveIff;
  119.   BEGIN
  120.     ClearMenuStrip(win);
  121.     ModifyIDCMP(win,IDCMPFlagSet{});
  122.     TextColorsOn;
  123.     fileok:=GetFileName(win,ADR("Save File"),ADR(fname));
  124.     TextColorsOff;
  125.     IF fileok THEN
  126.       INCL(win^.flags,rmbTrap);
  127.       SetZZZPointer(win); ShowTitle(scr,FALSE);
  128.       fileok:=SaveILBM(fname,scr,xminr,yminr,xmaxr,ymaxr,maxiter);
  129.       saved:=fileok;
  130.       SetNormalPointer(win); ShowTitle(scr,title); EXCL(win^.flags,rmbTrap);
  131.     END;
  132.     ModifyIDCMP(win,MENUFLAGS);
  133.     SetMenu(win);
  134.   END SaveIff;
  135.  
  136. (*** Prozeduren für Screen und Window ********************************)
  137.  
  138. PROCEDURE ColorTable; (* $E- *)
  139.   BEGIN
  140.     INLINE(00000H,00FF0H,00FD0H,00FB0H,00F80H,00F60H,00F40H,00F20H,
  141.        00F00H,00F02H,00F05H,00F07H,00F09H,00F0BH,00F0DH,00F0FH,
  142.        00D0FH,00B0FH,0090FH,0070FH,0050FH,0030FH,0010FH,0001FH,
  143.        0003FH,0005FH,0007FH,0009FH,000BFH,000DFH,000FFH,00DDDH);
  144.   END ColorTable;
  145.  
  146.  
  147. PROCEDURE CloseIfOpen;
  148.   BEGIN
  149.     thisTask:=CAST(ProcessPtr,FindTask(NIL));
  150.     thisTask^.windowPtr:=NIL;
  151.     IF win#NIL THEN CloseWindow(win); win:=NIL END;
  152.     IF scr#NIL THEN CloseScreen(scr); scr:=NIL END;
  153.   END CloseIfOpen;
  154.  
  155.  
  156. PROCEDURE CreateDisplay(w,h,d:INTEGER);
  157.   BEGIN
  158.     xres:=w; yres:=h; depth:=d; (* Werte für DrawFractal/Zoom merken *)
  159.     IF NOT saved THEN
  160.       mess:="This picture is not saved!|If you continue, it will be lost!";
  161.       yes:="CONTINUE"; no:="CANCEL";
  162.       IF NOT Request(win,mess,yes,no) THEN RETURN END;
  163.     END;
  164.     CloseIfOpen;
  165.     WITH ns DO
  166.       width:=w; height:=h; depth:=d; detailPen:=6; blockPen:=1;
  167.       viewModes:=ViewModeSet{};
  168.       IF w>320 THEN INCL(viewModes,hires) END;
  169.       IF h>256 THEN INCL(viewModes,lace) END;
  170.       type:=customScreen+ScreenFlagSet{screenBehind};
  171.       font:=ADR(attr); defaultTitle:=ADR(SCREENTITLE);
  172.       gadgets:=NIL; customBitMap:=NIL;
  173.     END;
  174.     scr:=OpenScreen(ns);
  175.     Assert(scr#NIL,ADR("OpenScreen() failed!"));
  176.     LoadRGB4(ADR(scr^.viewPort),ADR(ColorTable),32);
  177.     IF d=5 THEN maxcol:=31 ELSE maxcol:=15 END;
  178.     WITH nw DO
  179.       width:=w; height:=h; detailPen:=3; blockPen:=1;
  180.       idcmpFlags:=IDCMPFlagSet{menuVerify, menuPick, mouseButtons};
  181.       flags:=WindowFlagSet{reportMouse,backDrop,borderless,
  182.                            activate,noCareRefresh};
  183.       firstGadget:=NIL;checkMark:=NIL;title:=NIL;
  184.       screen:=scr; bitMap:=NIL;
  185.       minWidth:=0; minHeight:=0; maxWidth:=-1; maxHeight:=-1;
  186.       type:=customScreen;
  187.     END;
  188.     win:=OpenWindow(nw);
  189.     Assert(win#NIL,ADR("OpenWindow() failed!"));
  190.     rp:=win^.rPort;
  191.     FOR i:=0 TO h-1 DO  (* Zeilenadressen berechnen      *)
  192.       yadr[i]:=LONGINT(i)*LONGINT(rp^.bitMap^.bytesPerRow);
  193.     END;
  194.     ScreenToFront(scr);
  195.     thisTask:=CAST(ProcessPtr,FindTask(NIL)); (* Systemrequester auf *)
  196.     thisTask^.windowPtr:=win;              (* eigenem Screen.     *)
  197.     SetMenu(win);
  198.     title:=TRUE; ShowTitle(scr,title);
  199.   END CreateDisplay;
  200.  
  201.  
  202. (*** Prozeduren für Fraktalgrafik ************************************)
  203.  
  204. PROCEDURE DrawFractal(rmin,rmax,imin,imax:LONGREAL;
  205.               maxcol:INTEGER;
  206.               maxiter:LONGINT);
  207. VAR
  208.   r,cxr,cyr,dxr,dyr:LONGREAL;
  209.   lc:LONGINT;
  210.   exit:BOOLEAN;
  211.  
  212. PROCEDURE HLine(xmin,xmax,y:INTEGER); (* waagrechte Linie *)
  213. BEGIN
  214.   cxr:=rmin+LONGREAL(xmin)*dxr;cyr:=imin+LONGREAL(y)*dyr;
  215.   FOR i:=xmin TO xmax DO
  216.     lc:=Iterations(cxr,cyr,maxiter);cxr:=cxr+dxr;
  217.     SetPixel(i,yadr[y],lc,maxiter,maxcol,ADR(rp^.bitMap^.planes[0]));
  218.   END
  219. END HLine;
  220.  
  221. PROCEDURE VLine(ymin,ymax,x:INTEGER); (* senkrechte Linie *)
  222. BEGIN
  223.   cxr:=rmin+LONGREAL(x)*dxr;cyr:=imin+LONGREAL(ymin)*dyr;
  224.   FOR i:=ymin TO ymax DO
  225.     lc:=Iterations(cxr,cyr,maxiter);cyr:=cyr+dyr;
  226.     SetPixel(x,yadr[i],lc,maxiter,maxcol,ADR(rp^.bitMap^.planes[0]));
  227.   END
  228. END VLine;
  229.  
  230. PROCEDURE Rectangle(xmin,ymin,xmax,ymax:INTEGER);
  231.   VAR
  232.     eq:BOOLEAN;
  233.     dx2,dy2,k:INTEGER;
  234.   BEGIN
  235.     IF exit THEN RETURN END;
  236.     msg:=GetMsg(win^.userPort);
  237.     IF msg#NIL THEN
  238.       ReplyMsg(msg);
  239.       IF msg^.code=ESCAPE THEN exit:=TRUE END;
  240.     END;
  241.     dx2:=(xmax-xmin);dy2:=(ymax-ymin);
  242.     IF (dx2<2) OR (dy2<2) THEN RETURN END;
  243.     IF (dx2<LIMIT) OR (dy2<LIMIT) THEN
  244.       FOR k:=ymin+1 TO ymax-1 DO HLine(xmin+1,xmax-1,k) END;
  245.       RETURN;
  246.     END;
  247.     dx2:=(1+dx2) DIV 2;dy2:=(1+dy2) DIV 2;
  248.     lc:=GetPixel(xmin,yadr[ymin],depth, ADR(rp^.bitMap^.planes[0]));
  249.     i:=xmin;eq:=TRUE;
  250.     REPEAT
  251.       INC(i);
  252.       eq:=(lc=GetPixel(i,yadr[ymin],depth,ADR(rp^.bitMap^.planes[0]))) &
  253.           (lc=GetPixel(i,yadr[ymax],depth,ADR(rp^.bitMap^.planes[0])));
  254.     UNTIL (i=xmax) OR NOT eq;
  255.     IF eq THEN
  256.       i:=ymin;
  257.       REPEAT
  258.         INC(i);
  259.         eq:=(lc=GetPixel(xmin,yadr[i],depth,ADR(rp^.bitMap^.planes[0]))) &
  260.             (lc=GetPixel(xmax,yadr[i],depth,ADR(rp^.bitMap^.planes[0])));
  261.       UNTIL (i=ymax) OR NOT eq;
  262.     END;
  263.     IF eq THEN (* ganzer Rand einfärbig => Rechteck einfärbig *)
  264.       SetAPen(rp,lc);RectFill(rp,xmin,ymin,xmax,ymax);
  265.     ELSE
  266.       (* Rechteck vierteln, und alle Viertel testen        *)
  267.       HLine(xmin+1,xmax-1,ymin+dy2);
  268.       VLine(ymin+1,ymax-1,xmin+dx2);
  269.       Rectangle(xmin,ymin,xmin+dx2,ymin+dy2);
  270.       Rectangle(xmin+dx2,ymin,xmax,ymin+dy2);
  271.       Rectangle(xmin,ymin+dy2,xmin+dx2,ymax);
  272.       Rectangle(xmin+dx2,ymin+dy2,xmax,ymax);
  273.     END;
  274.   END Rectangle;
  275.  
  276.   BEGIN    (* DrawFractal *)
  277.     INCL(win^.flags,rmbTrap);
  278.     ShowTitle(scr,FALSE); SetZZZPointer(win);
  279.     ModifyIDCMP(win,IDCMPFlagSet{rawKey});
  280.     ClearMenuStrip(win);
  281.     saved:=FALSE;
  282.     SetRast(rp,0);
  283.     dxr:=(rmax-rmin)/LONGREAL(xres);
  284.     dyr:=(imax-imin)/LONGREAL(yres);
  285.     IF zx#-1 THEN (* wenn Zoomrahmen, dann diesen Ausschnitt zeichnen *)
  286.       r:=rmin;
  287.       rmin:=r+LONGREAL(zx-zdx)*dxr;
  288.       rmax:=r+LONGREAL(zx+zdx)*dxr;
  289.       r:=imin;
  290.       imin:=r+LONGREAL(zy-zdy)*dyr;
  291.       imax:=r+LONGREAL(zy+zdy)*dyr;
  292.       dxr:=(rmax-rmin)/LONGREAL(xres);
  293.       dyr:=(imax-imin)/LONGREAL(yres);
  294.       zx:=-1; (* Damit der Rahmen anschließend nicht gezeichnet wird *)
  295.     END;
  296.     xminr:=rmin; xmaxr:=rmax; yminr:=imin; ymaxr:=imax;
  297.     xmin:=rmin; xmax:=rmax; ymin:=imin; ymax:=imax;
  298.     exit:=FALSE;
  299.     HLine(0,xres-1,0);VLine(0,yres-1,xres-1); (* Anfangs-  *)
  300.     HLine(0,xres-1,yres-1);VLine(0,yres-1,0); (* rechteck  *)
  301.     Rectangle(0,0,xres-1,yres-1);
  302.     EXCL(win^.flags,rmbTrap);
  303.     SetMenu(win);
  304.     ModifyIDCMP(win,IDCMPFlagSet{menuPick,menuVerify,mouseButtons});
  305.     ShowTitle(scr,title); SetNormalPointer(win);
  306.   END DrawFractal;
  307.  
  308.  
  309. (*** Prozeduren für Zoom *********************************************)
  310.  
  311. PROCEDURE DrawFrame(x1,y1,dx,dy:INTEGER);
  312.   BEGIN
  313.     SetAPen(rp,15); (* 4 Bitplanes beeinflussen *)
  314.     SetDrMd(rp,DrawModeSet{complement}); (* Bild nicht zerstören *)
  315.     Move(rp,x1-dx,y1-dy);
  316.     Draw(rp,x1+dx,y1-dy);Draw(rp,x1+dx,y1+dy);
  317.     Draw(rp,x1-dx,y1+dy);Draw(rp,x1-dx,y1-dy);
  318.     SetDrMd(rp,jam1);
  319.   END DrawFrame;
  320.  
  321.  
  322. PROCEDURE Zoom; (* Ausschnitt wählen, unverzerrt!        *)
  323.   VAR
  324.     x1,y1,dx,dy,mx,my:INTEGER;
  325.     r,dxr,dyr:LONGREAL;
  326.   BEGIN
  327.     IF zx#-1 THEN DrawFrame(zx,zy,zdx,zdy) END;    (* Rahmen löschen *)
  328.     xmin:=xminr; xmax:=xmaxr;
  329.     ymin:=yminr; ymax:=ymaxr;
  330.     ModifyIDCMP(win,IDCMPFlagSet{mouseButtons,mouseMove});
  331.     ShowTitle(scr,FALSE);
  332.     SetZoomPointer(win);
  333.     REPEAT                          (* warten bis Maustaste gedrückt *)
  334.       WaitPort(win^.userPort);
  335.       msg:=GetMsg(win^.userPort);
  336.       ReplyMsg(msg);
  337.     UNTIL (mouseButtons IN msg^.class);
  338.     IF (msg^.code = menuDown) THEN                 (* RMB => Abbruch *)
  339.       ShowTitle(scr,title); SetNormalPointer(win);
  340.       ModifyIDCMP(win,MENUFLAGS);
  341.       zx:=-1;
  342.       RETURN;
  343.     END;
  344.     IF (msg^.code = selectDown) THEN               (* LMB => Zoomen  *)
  345.       x1:=msg^.mouseX; y1:=msg^.mouseY;            (* Mittelpunkt    *)
  346.       dx:=0;dy:=0;
  347.       DrawFrame(x1,y1,dx,dy);              (* ersten Rahmen zeichnen *)
  348.       LOOP
  349.         msg:=GetMsg(win^.userPort);
  350.         IF msg#NIL THEN
  351.           IF (mouseButtons IN msg^.class) & (msg^.code = menuDown) THEN
  352.             DrawFrame(x1,y1,dx,dy);                (* Rahmen löschen *)
  353.             zx:=-1;                   (* merken, daß Rahmen gelöscht *)
  354.             ReplyMsg(msg);
  355.             ShowTitle(scr,title); SetNormalPointer(win);
  356.             ModifyIDCMP(win,MENUFLAGS);
  357.             RETURN;
  358.           END;
  359.           IF (mouseButtons IN msg^.class) & (msg^.code = selectUp) THEN
  360.             (* Position der Maus merken (für Rechteck)     *)
  361.             mx:=msg^.mouseX;my:=msg^.mouseY;
  362.             ReplyMsg(msg);
  363.             zx:=x1; zy:=y1; zdx:=dx; zdy:=dy; (* Merken, wo der Rahmen ist *)
  364.             EXIT;
  365.           END;
  366.           IF (mouseMove IN msg^.class) THEN
  367.             DrawFrame(x1,y1,dx,dy); (* alten Rand löschen  *)
  368.             mx:=msg^.mouseX;my:=msg^.mouseY;
  369.             dx:=x1-mx; dy:=y1-my;
  370.             dx:=ABS(dx); dy:=ABS(dy);
  371.             (* Skalierung. hoffentlich richtig          *)
  372.             IF (dy>dx) THEN
  373.               dx:=(xres*dy)/yres;
  374.             ELSE
  375.               dy:=(yres*dx)/xres;
  376.             END;
  377.             DrawFrame(x1,y1,dx,dy); (* neuen Rand zeichnen *)
  378.           END;
  379.           ReplyMsg(msg);
  380.         END;
  381.       END;
  382.     END;
  383.     ShowTitle(scr,title); SetNormalPointer(win);
  384.     ModifyIDCMP(win,MENUFLAGS);
  385.   END Zoom;
  386.  
  387.  
  388. (*** Prozeduren für Userinterface ************************************)
  389.  
  390. PROCEDURE TextColorsOn;
  391.   BEGIN
  392.     SetRGB4(ADR(scr^.viewPort),1,13,13,13);
  393.     SetRGB4(ADR(scr^.viewPort),2,8,8,8);
  394.     SetRGB4(ADR(scr^.viewPort),3,5,5,5);
  395.     SetRGB4(ADR(scr^.viewPort),30,5,5,5);
  396.     SetRGB4(ADR(scr^.viewPort),14,5,5,5);
  397.     SetRGB4(ADR(scr^.viewPort),28,14,14,14);
  398.     SetRGB4(ADR(scr^.viewPort),12,14,14,14);
  399.     SetRGB4(ADR(scr^.viewPort),15,13,13,13);
  400.   END TextColorsOn;
  401.  
  402. PROCEDURE TextColorsOff;
  403.   BEGIN
  404.     LoadRGB4(ADR(scr^.viewPort),ADR(ColorTable),32);
  405.   END TextColorsOff;
  406.  
  407. PROCEDURE MenuHandler;
  408.   VAR
  409.     selection, menuNum, itemNum, subNum : CARDINAL;
  410.   BEGIN
  411.     LOOP
  412.       msg:=GetMsg(win^.userPort);
  413.       IF msg=NIL THEN EXIT END;
  414.       class:=msg^.class;
  415.       code :=msg^.code;
  416.       IF class=IDCMPFlagSet{menuVerify} THEN
  417.         TextColorsOn;
  418.       END;
  419.       ReplyMsg(msg); (* muß nach menuVerify-Abfrage stehen *)
  420.       IF (mouseButtons IN class) & (code=menuUp) THEN
  421.         TextColorsOff;
  422.       END;
  423.       IF menuPick IN class THEN
  424.         selection:=code;
  425.         WHILE selection#menuNull DO
  426.           menuNum:=MenuNum(selection);
  427.           itemNum:=ItemNum(selection);
  428.           subNum :=SubNum(selection);
  429.           CASE menuNum OF
  430.             0 : (* Project Menü *)
  431.             CASE itemNum OF
  432.               0 : LoadIff(TRUE); zx:=-1;|
  433.               1 : SaveIff;| (* -""- *)
  434.               2 : ClearMenuStrip(win);
  435.                   ModifyIDCMP(win,IDCMPFlagSet{});
  436.                   TextColorsOn; Info(win); TextColorsOff;
  437.                   SetMenu(win);
  438.                   ModifyIDCMP(win,MENUFLAGS);
  439.                   EXIT;|
  440.               3 : IF NOT saved THEN
  441.                     mess:="Really quit?!|Picture will be lost!";
  442.                     yes:="QUIT!"; no:="NO!";
  443.                     IF Request(win,mess,yes,no) THEN
  444.                       QUIT:=TRUE; EXIT;
  445.                     END
  446.                   ELSE
  447.                     QUIT:=TRUE; EXIT;
  448.                   END;|
  449.               ELSE;
  450.             END;|
  451.             1 : (* Setup Menü *)
  452.             CASE itemNum OF
  453.               0 : (* Auflösung  *)
  454.               CASE subNum OF
  455.                 0 : zx:=-1; CreateDisplay(320, 256, 5); EXIT;|
  456.                 1 : zx:=-1; CreateDisplay(640, 256, 4); EXIT;|
  457.                 2 : zx:=-1; CreateDisplay(640, 512, 4); EXIT;|
  458.                 ELSE;
  459.               END;|
  460.               1 : (* Algorithmen *)
  461.               CASE subNum OF
  462.                 0 : Iterations:=FastIter16;|
  463.                 1 : Iterations:=FastIter32;|
  464.                 2 : Iterations:=LongRealIter;|
  465.                 ELSE;
  466.               END;|
  467.               2 : ClearMenuStrip(win);
  468.                   ModifyIDCMP(win,IDCMPFlagSet{});
  469.                   TextColorsOn;
  470.                   GetLimits(scr,xmin,xmax,ymin,ymax,maxiter);
  471.                   TextColorsOff;
  472.                   IF (zx#-1) AND
  473.                     ((xminr#xmin) OR (xmaxr#xmax) OR   (* bei neuen *)
  474.                     (yminr#ymin) OR (ymaxr#ymax)) THEN (* Grenzen   *)
  475.                     DrawFrame(zx,zy,zdx,zdy); zx:=-1;  (* Rahmen    *)
  476.                   END;                                 (* löschen   *)
  477.           SetMenu(win);
  478.                   ModifyIDCMP(win,MENUFLAGS);|
  479.               ELSE;
  480.             END;|
  481.             2 : (* Action Menü *)
  482.             CASE itemNum OF
  483.               0 : TextColorsOff; title:=NOT title; ShowTitle(scr, title);|
  484.               1 : TextColorsOff; Zoom;|
  485.               2 : TextColorsOff;
  486.                   DrawFractal(xmin,xmax,ymin,ymax,maxcol,maxiter); |
  487.               ELSE;
  488.             END;|
  489.             ELSE;
  490.           END;
  491.           selection:=NextSelect(selection);
  492.         END;   (* WHILE  *)
  493.       END;     (* IF *)
  494.     END;     (* LOOP  *)
  495.   END MenuHandler;
  496.  
  497.  
  498. PROCEDURE CleanUp;
  499.   BEGIN
  500.     CloseIfOpen;
  501.     IF topaz80#NIL THEN CloseFont(topaz80) END;
  502.   END CleanUp;
  503.  
  504.  
  505.   BEGIN
  506.     TermProcedure(CleanUp);
  507.     WITH attr DO
  508.       name :=ADR(TOPAZ); ySize:=8; style:=normalFont;
  509.       flags:=FontFlagSet{romFont,designed};
  510.     END;
  511.     topaz80:=OpenFont(ADR(attr));
  512.     saved:=TRUE;
  513.     zx:=-1;                     (* noch kein Zoomrahmen gezeichnet *)
  514.     title:=TRUE;                              (* Titlebar sichtbar *)
  515.     QUIT:=FALSE;
  516.     xres:=320; yres:=256; depth:=5;        (* Anfangsauflösung *)
  517.     Iterations:=FastIter16;
  518.     fname:="FFEX_Start.pic";
  519.     CreateDisplay(xres, yres, depth);
  520.     LoadIff(FALSE);
  521.     REPEAT
  522.       WaitPort(win^.userPort);
  523.       MenuHandler;
  524.     UNTIL QUIT;
  525.   END FFEX.
  526.